home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.05 May 93 / Efficient BlockMove / MyMemMgr.c next >
Encoding:
C/C++ Source or Header  |  1993-03-13  |  6.2 KB  |  362 lines  |  [TEXT/KAHL]

  1. /*****************************************************
  2.  * MyMemMgr.c
  3.  *
  4.  * Optimized 68040 versions of BlockMove, NewPtrClear
  5.  * and NewHandleClear.
  6.  *
  7.  * Mike Scanlin  8 Mar 1992
  8.  ****************************************************/
  9.  
  10. #include "MyMemMgr.h"
  11.  
  12. /* Think C doesn't know this instruction:
  13.  * Move16 (A0)+,(A1)+
  14.  */
  15. #define Move16A0ToA1        DC.W    0xF620, 0x9000
  16.  
  17. /* Move16BytesPerLoop must be a power of 2 and
  18.  * agree with # of Move16 instructions per loop
  19.  * in MyBlockMoveData
  20.  */
  21. #define Move16BytesPerLoop        64
  22.  
  23. /* LongBytesPerLoop must be a power of 2 and 
  24.  * agree with # of Move.L instructions per loop 
  25.  * in MyBlockMoveData
  26.  */
  27. #define LongBytesPerLoop        16
  28.  
  29. /* SmallNumBytes can't be less than 16 */
  30. #define SmallNumBytes            16
  31.  
  32. /* ClearLongBytesPerLoop must be a power of 2 and
  33.  * agree with # of Move.L instructions per loop
  34.  * in MyNewPtrClear
  35.  */
  36. #define ClearLongBytesPerLoop    64
  37.  
  38. /* ClearBytesPerLoop must be a power of 2 and
  39.  * agree with # of Move.L instructions per loop
  40.  * in MyNewPtrClear
  41.  */
  42. #define ClearBytesPerLoop        8
  43.  
  44. /* gIn24BitMode needs to be set to TRUE if the
  45.  * system is in 24-bit mode when you call
  46.  * MyBlockMoveData; FALSE if in 32-bit mode
  47.  */
  48. Boolean        gIn24BitMode;
  49.  
  50.  
  51. /*****************************************************
  52.  * MyBlockMoveData
  53.  *
  54.  * Equivalent to the system's BlockMove except that
  55.  * it doesn't flush the 68040 data cache on exit so
  56.  * it shouldn't be used to BlockMove code.
  57.  ****************************************************/
  58. void
  59. MyBlockMoveData(const void *srcPtr, void *destPtr,
  60.     Size byteCount)
  61. {
  62.     asm {
  63.  
  64.     ;get parameters into registers
  65.  
  66.         Move.L    srcPtr,D0
  67.         Move.L    destPtr,D1
  68.         Move.L    byteCount,D2
  69.  
  70.     ;if we're in 24-bit mode we need to StripAddress
  71.     ;the addresses before comparison
  72.         
  73.         Tst.B    gIn24BitMode
  74.         Beq.S    @1
  75.         Andi.L    #0x00FFFFFF,D0
  76.         Andi.L    #0x00FFFFFF,D1
  77.     
  78.     @1    Move.L    D0,A0
  79.         Move.L    D1,A1
  80.             
  81.     ;if dst > src then we might need to move bytes
  82.     ;last to first
  83.     
  84.         Cmp.L    A0,A1
  85.         Bhi.S    @CheckForNonOverlapping
  86.     
  87.     ;if dst == src then we're done
  88.     
  89.         Beq.S    @8
  90.  
  91.     MoveFrontToBack:
  92.     
  93.     ;if we're only doing a few bytes, skip the
  94.     ;tricky stuff
  95.     
  96.         Cmp.L    #SmallNumBytes,D2
  97.         Bls.S    @10
  98.  
  99.     ;if the low 4 bits of src and dst are equal
  100.     ;then we can use Move16
  101.  
  102.         Andi    #0x000F,D0
  103.         Andi.L    #0x0000000F,D1
  104.         Cmp        D0,D1
  105.         Bne.S    @ForwardLongLoop
  106.         Tst        D0
  107.         Beq.S    @4
  108.  
  109.     ;do the first few bytes at the beginning,
  110.     ;until we're 16-byte aligned
  111.  
  112.         Eori    #0x000F,D0    ;D0 = 16 - D0
  113.     @2    Move.B    (A0)+,(A1)+
  114.     @3    Dbra    D0,@2
  115.         Sub.L    D1,D2
  116.  
  117.     ;move groups of Move16BytesPerLoop bytes
  118.     
  119.     @4    Move.L    D2,D1
  120.         Andi.L    #Move16BytesPerLoop-1,D2
  121.         Sub.L    D2,D1
  122.         Beq.S    @ForwardLongLoop
  123.         
  124.         Nop     ;compensate for chip bug on some 040s
  125.         
  126.     @5    Move16A0ToA1
  127.         Move16A0ToA1
  128.         Move16A0ToA1
  129.         Sub.L    #Move16BytesPerLoop,D1
  130.         Move16A0ToA1
  131.         Bne.S    @5
  132.  
  133.     ForwardLongLoop:
  134.  
  135.     ;move groups of LongBytesPerLoop bytes
  136.  
  137.         Move.L    D2,D1
  138.         Bra.S    @7
  139.  
  140.     @6    Move.L    (A0)+,(A1)+
  141.         Move.L    (A0)+,(A1)+
  142.         Move.L    (A0)+,(A1)+
  143.         Move.L    (A0)+,(A1)+
  144.  
  145.     @7    Sub.L    #LongBytesPerLoop,D1
  146.         Bpl.S    @6
  147.     
  148.     ;move the last few remaining bytes
  149.     
  150.         Andi    #LongBytesPerLoop-1,D2
  151.     @8    Beq.S    @Exit
  152.         Subq    #1,D2
  153.     @9    Move.B    (A0)+,(A1)+
  154.     @10    Dbra    D2,@9
  155.  
  156.         Bra.S    @Exit
  157.  
  158.     CheckForNonOverlapping:
  159.     
  160.     ;if we're not overlapping, use the front-to-back
  161.     ;loops so Move16 has a chance
  162.     
  163.         Sub.L    A0,D1
  164.         Cmp.L    D1,D2
  165.         Bhi.S    @MoveBackToFront
  166.         Move    A1,D1
  167.         Bra.S    @MoveFrontToBack
  168.  
  169.     MoveBackToFront:
  170.  
  171.     ;set the pointers to one past the last byte
  172.     
  173.         Add.L    D2,A0
  174.         Add.L    D2,A1
  175.  
  176.     ;if we're only doing a few bytes, skip the
  177.     ;tricky stuff
  178.  
  179.         Cmp.L    #SmallNumBytes,D2
  180.         Bls.S    @14
  181.  
  182.     ;move groups of LongBytesPerLoop/2 bytes
  183.  
  184.         Move.L    D2,D1
  185.         Bra.S    @12
  186.     
  187.     @11    Move.L    -(A0),-(A1)
  188.         Move.L    -(A0),-(A1)
  189.         
  190.     @12    Sub.L    #LongBytesPerLoop/2,D1
  191.         Bpl.S    @11
  192.     
  193.     ;move the last few remaining bytes
  194.  
  195.         Andi    #(LongBytesPerLoop/2)-1,D2
  196.         Beq.S    @Exit
  197.         Subq    #1,D2
  198.     @13    Move.B    -(A0),-(A1)
  199.     @14    Dbra    D2,@13
  200.     
  201.     Exit:
  202.     
  203.     }
  204. }
  205.  
  206.  
  207. /* Declare extra entry points so that functions
  208.  * can share the memory clearing code.
  209.  */
  210. void ClearHandleBytes(void);
  211. void ClearPtrBytes(void);
  212. void ClearBytes(void);
  213.  
  214. /*****************************************************
  215.  * MyNewHandleClear
  216.  *
  217.  * Faster version of the system's NewHandleClear.
  218.  ****************************************************/
  219. Handle
  220. MyNewHandleClear(Size theSize)
  221. {
  222.     register Handle        h;
  223.     
  224.     if (h = NewHandle(theSize)) {
  225.     
  226.         asm {
  227.             Bra        ClearHandleBytes;
  228.         }
  229.     }
  230.     
  231.     return (h);
  232. }
  233.  
  234.  
  235. /*****************************************************
  236.  * MyNewHandleSysClear
  237.  *
  238.  * Faster version of the system's NewHandleSysClear.
  239.  ****************************************************/
  240. Handle
  241. MyNewHandleSysClear(Size theSize)
  242. {
  243.     register Handle        h;
  244.     
  245.     if (h = NewHandleSys(theSize)) {
  246.  
  247.         asm {
  248.         
  249.         extern ClearHandleBytes:
  250.     
  251.             Move.L    h,A0
  252.             Move.L    (A0),A0
  253.             Bra        ClearBytes
  254.         }
  255.     }
  256.     
  257.     return (h);
  258. }
  259.  
  260.  
  261. /*****************************************************
  262.  * MyNewPtrSysClear
  263.  *
  264.  * Faster version of the system's NewPtrSysClear.
  265.  ****************************************************/
  266. Ptr
  267. MyNewPtrSysClear(Size theSize)
  268. {
  269.     register Ptr        p;
  270.     
  271.     if (p = NewPtrSys(theSize)) {
  272.     
  273.         asm {
  274.             Bra        ClearPtrBytes
  275.         }
  276.     }
  277.     
  278.     return (p);
  279. }
  280.  
  281.  
  282. /*****************************************************
  283.  * MyNewPtrClear
  284.  *
  285.  * Faster version of the system's NewPtrClear.
  286.  ****************************************************/
  287. Ptr
  288. MyNewPtrClear(Size theSize)
  289. {
  290.     register Ptr        p;
  291.     
  292.     if (p = NewPtr(theSize)) {
  293.     
  294.         asm {
  295.  
  296.     extern ClearPtrBytes:
  297.     
  298.             Move.L    p,A0
  299.                     
  300.     extern ClearBytes:
  301.  
  302.         ;init bytesUntilDone
  303.         
  304.             Move.L    theSize,D2
  305.         
  306.         ;init the seed value
  307.         
  308.             Moveq    #0,D0
  309.     
  310.         ;clear groups of ClearLongBytesPerLoop bytes
  311.     
  312.             Move.L    D2,D1
  313.             Bra.S    @2
  314.         
  315.         @1    Move.L    D0,(A0)+
  316.             Move.L    D0,(A0)+
  317.             Move.L    D0,(A0)+
  318.             Move.L    D0,(A0)+
  319.             Move.L    D0,(A0)+
  320.             Move.L    D0,(A0)+
  321.             Move.L    D0,(A0)+
  322.             Move.L    D0,(A0)+
  323.             Move.L    D0,(A0)+
  324.             Move.L    D0,(A0)+
  325.             Move.L    D0,(A0)+
  326.             Move.L    D0,(A0)+
  327.             Move.L    D0,(A0)+
  328.             Move.L    D0,(A0)+
  329.             Move.L    D0,(A0)+
  330.             Move.L    D0,(A0)+
  331.             
  332.         @2    Sub.L    #ClearLongBytesPerLoop,D1
  333.             Bpl.S    @1
  334.         
  335.         ;clear groups of ClearBytesPerLoop bytes
  336.  
  337.             Andi    #ClearLongBytesPerLoop-1,D2
  338.             Move    D2,D1
  339.             Bra.S    @4
  340.  
  341.         @3    Move.L    D0,(A0)+
  342.             Move.L    D0,(A0)+
  343.             
  344.         @4    Subq    #ClearBytesPerLoop,D1
  345.             Bpl.S    @3
  346.         
  347.         ;clear the last few remaining bytes
  348.     
  349.             Andi    #ClearBytesPerLoop-1,D2
  350.             Beq.S    @Exit
  351.             Subq    #1,D2
  352.         @5    Move.B    D0,(A0)+
  353.             Dbra    D2,@5
  354.         
  355.         Exit:
  356.         
  357.         }
  358.     }
  359.     
  360.     return (p);
  361. }
  362.